{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 问题：Django 本身提供了 runserver，为什么不能用来部署？\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "面试官想从这道题中考察面试人什么？\n",
    "在这道题的背后，面试官可能会把问题引向 WSGI 或 uwsgi，这是部署 Django 必须要知道的东西。另外，还可能问一些关于 Django 项目的配置文件 settings.py。\n",
    "\n",
    "答案\n",
    "Django 的官方文档中已经明确指出:\n",
    "\n",
    "DO NOT USE THIS SERVER IN A PRODUCTION SETTING. It has not gone through security audits or performance tests. (And that’s how it’s gonna stay. We’re in the business of making Web frameworks, not Web servers, so improving this server to be able to handle a production environment is outside the scope of Django.) 请勿直接在生产环境中使用它运行服务。因为没有经过安全和性能测试。\n",
    "\n",
    "runserver 方法是调试 Django 时经常用到的运行方式，使用的是 WSGI server，主要在测试和开发中使用，并且 runserver 开启的方式也是单进程 。\n",
    "\n",
    "拓展\n",
    "Django 是一个 Web 框架，框架的作用在于处理 request 和 response。Web 框架主要搞定 MVC 架构、URL 映射、会话机制、 用户认证、数据库访问、模板引擎、内容缓存机制、安全性保障等，为日益复杂和规模庞大的 Web 应用开发提供便利性，其他的不是框架所关心的内容。Django 所提供的是一个开发服务器，这个开发服务器使用的是 Python 自带的 simple HTTPServer 创建的，在安全性和性能上都是不适合生产环境的。下图（来自 pycon）中指出了 web 相关的技术关键词。\n",
    "\n",
    "图片描述\n",
    "\n",
    "当请求到达服务器时，应将其传递到专用的 Web 服务器。Nginx 就是一个 Web 服务器的例子。Nginx 非常适合从磁盘提供静态文件（例如，css 和 js 文件）并一次处理多个请求。如果该请求不是针对静态文件的，而是应由应用程序处理，则将 Web 服务器配置为将该请求传递给下一个组件。\n",
    "\n",
    "下一个组件是应用程序服务器。它得到 request 请求，并使用它们来构造可供 Django 使用的 Python 对象。 Web 服务器向外部世界提供文件系统重点文件（HTML，图像，CSS 等）。但是，它无法直接与 Django 应用程序对话；它需要一些东西来运行该应用程序，从 Web 客户端（例如浏览器）接收它的请求并返回响应。WSGI 就是做这么一件事的，它的全称是 Web Server Gateway Interface，是一个协议，它是 Web 服务器和 Web 应用的 Python 标准，描述 Web 服务器如何与 Web 应用程序通信以及如何将 Web 应用程序链接在一起以处理一个请求的规范。在 Django 项目中有一个文件 wsgi.py，这个模块中包含了一个 WSGI application 对象，而应用服务器就是通过这个对象与你的代码交互。比如，在开发环境中，Django 的默认服务器（ runserver 命令），从 settings.py 的配置项 WSGI_APPLICATION 中获取这个对象的路径。而生产环境下，可以通过 uwsgi uwsgi.ini 去发布应用。\n",
    "\n",
    "WSGI 协议主要包括 server 和 application 两部分：\n",
    "\n",
    "WSGI Server 负责从客户端接收请求，将 request 转发给 application，将 application 返回的 response 返回给客户端；\n",
    "WSGI Application 接收由 server 转发的 request，处理请求，并将处理结果返回给 server；\n",
    "application 中可以包括多个栈式的中间件 (middlewares)，这些中间件需要同时实现 server 与 application，因此可以在 WSGI 服务器与 WSGI 应用之间起调节作用：对服务器来说，中间件扮演应用程序，对应用程序来说，中间件扮演服务器。\n",
    "而 uWSGI 实现了 WSGI 的所有接口，是一个快速、自我修复、开发人员和系统管理员友好的服务器。uWSGI 代码完全用 C 编写，效率高、性能稳定。uWSGI 模块以客户端 - 服务端模式运行，Web 服务器（例如 nginx，Apache）与一个 django-uwsgi “worker” 进程交互，提供动态内容。\n",
    "\n",
    "nginx 是免费开源的高性能 HTTP 服务器和反向代理，以及 IMAP / POP3 代理服务器。nginx 和 uWSGI 是 Django 部署的不错选择，但它们不是唯一的选择，也不是 “官方” 的选择。\n",
    "\n",
    "在大型部署中，我们可以通过用 uwsgi 去运行 Django 应用，而 nginx 可以通过 site 配置文件指定处理需要 Django 干预的请求。\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
